package servicedevmap

import (
	"emsctrl/public"
	"emsctrl/rpcClient"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"strconv"
)

type RegInfo struct {
	Key    string
	SetVal float32
	Val    float32
	Addr   int32
	PType  string
}

type DevReg struct {
	RegMap map[string]RegInfo
}

var StationMap map[int]map[string]map[string]DevReg

const (
	DEV_MAP_FILE = "map表.xlsx"
)

func devAnalysis_string(info []string) {
	var ClusterMap map[string]map[string]DevReg
	var DevMap map[string]DevReg
	for i, s := range info {
		switch i {
		case 0:
			fmt.Println(s)
			atoi, err := strconv.Atoi(s)
			if err != nil {
				fmt.Println(err)
			} else {
				if _, ok := StationMap[atoi]; ok {
					ClusterMap = StationMap[atoi]
				} else {
					StationMap[atoi] = make(map[string]map[string]DevReg)
					ClusterMap = StationMap[atoi]
				}
			}
		case 1:
			if _, ok := ClusterMap[s]; ok {
				DevMap = ClusterMap[s]
			} else {
				ClusterMap[s] = make(map[string]DevReg)
				DevMap = ClusterMap[s]
			}
		case 2:
			if _, ok := DevMap[s]; ok {
			} else {
				DevMap[s] = DevReg{}
			}
		}
	}
}

func init() {

	StationMap = make(map[int]map[string]map[string]DevReg)
	file, err := excelize.OpenFile(DEV_MAP_FILE)
	if err != nil {
		panic(err)
	}
	rows := file.GetRows("devinfo")
	for i, row := range rows {
		fmt.Println(i, row, len(row))
		if i == 0 {
			continue
		}
		devAnalysis_string(row)
	}
	p := pcsdevMap{}
	rows = file.GetRows("PCS")
	for i, row := range rows {
		fmt.Println(i, row, len(row))
		if i == 0 {
			continue
		}
		p.Analysis_string(row)
	}
	b := bmsdevMap{}
	rows = file.GetRows("BMS")
	for i, row := range rows {
		fmt.Println(i, row, len(row))
		if i == 0 {
			continue
		}
		b.Analysis_string(row)
	}

	m := meterdevMap{}
	rows = file.GetRows("METER")
	for i, row := range rows {
		fmt.Println(i, row, len(row))
		if i == 0 {
			continue
		}
		m.Analysis_string(row)
	}

	fmt.Println(StationMap)
}

var G_curr_policy *public.CurrentPolicy

func Run() {
	fmt.Println("map run")
	G_curr_policy = public.Get_Current_Polic()
}

const (
	REMOTE_CTRL = "yk"
	REMOTE_ADJ  = "yt"
)

func pcsRpcSet(val float32, mapReg string) {
	for i, m := range StationMap {
		for s, m2 := range m {
			if s == "pcs" {
				for s2, reg := range m2 {
					if _, ok := reg.RegMap[mapReg]; ok {
						info := reg.RegMap[mapReg]
						if val != info.Val {
							switch reg.RegMap[mapReg].PType {
							case "yt":
								rpcClient.SetDeviceRet(s2, reg.RegMap[mapReg].Addr, 2, val)
							case "yk":
								rpcClient.SetDeviceRet(s2, reg.RegMap[mapReg].Addr, 1, val)
							}
							//rpcClient.SetDeviceRet(s2, reg.RegMap[mapReg].Addr, 1, val)
							reg.RegMap[mapReg] = info
							StationMap[i][s][s2] = reg
						}
						//if info.SetVal != info.Val {
						//	rpcClient.SetDeviceRet(s2, reg.RegMap[PCS_OPEN].Addr, 1, val)
						//	reg.RegMap[mapReg] = info
						//	StationMap[i][s][s2] = reg
						//}
					}
				}
			}
		}
	}
}

func PcsClose(val float32) {
	pcsRpcSet(val, PCS_CLOSE)
}

func PcsRemote(val float32) {
	pcsRpcSet(val, PCS_REMOTE_SET)
}
func PcsOpen(val float32) {
	pcsRpcSet(val, PCS_OPEN)
}

func PcsActionPower(power float32) {
	pcsNum := 0
	for i, m := range StationMap {
		for s, m2 := range m {
			if s == "pcs" {
				pcsNum += len(m2)
				for s2, reg := range m2 {
					if _, ok := reg.RegMap[PCS_YGGL]; ok {
						info := reg.RegMap[PCS_YGGL]
						info.SetVal = power / float32(pcsNum)
						if info.SetVal != info.Val {
							switch reg.RegMap[PCS_YGGL].PType {
							case "yt":
								rpcClient.SetDeviceRet(s2, reg.RegMap[PCS_YGGL].Addr, 2, power/float32(pcsNum))
							case "yk":
								rpcClient.SetDeviceRet(s2, reg.RegMap[PCS_YGGL].Addr, 1, power/float32(pcsNum))
							}
							//rpcClient.SetDeviceRet(s2, reg.RegMap[PCS_YGGL].Addr, 2, power/float32(pcsNum))
							reg.RegMap[PCS_YGGL] = info
							StationMap[i][s][s2] = reg
						}
					}
				}
			}
		}
	}
}

func PvActionPower(power float32) {
	PvNum := 0
	for i, m := range StationMap {
		for s, m2 := range m {
			if s == "pv" {
				PvNum += len(m2)
				for s2, reg := range m2 {
					if _, ok := reg.RegMap[PV_YGGL]; ok {
						info := reg.RegMap[PV_YGGL]
						info.SetVal = power / float32(PvNum)
						if info.SetVal != info.Val {
							switch reg.RegMap[PCS_YGGL].PType {
							case "yt":
								rpcClient.SetDeviceRet(s2, reg.RegMap[PV_YGGL].Addr, 2, power/float32(PvNum))
							case "yk":
								rpcClient.SetDeviceRet(s2, reg.RegMap[PV_YGGL].Addr, 1, power/float32(PvNum))
							}
							//rpcClient.SetDeviceRet(s2, reg.RegMap[PCS_YGGL].Addr, 2, power/float32(pcsNum))
							reg.RegMap[PV_YGGL] = info
							StationMap[i][s][s2] = reg
						}
					}
				}
			}
		}
	}
}
